﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;

namespace ParkingLot.Utility.SerializeHelp
{
    /// <summary>
    /// 将类和XML互相转换的帮助类
    /// </summary>
    public class XmlHelp
    {
        /// <summary>
        /// 将实体类序列化为字符串
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public static string XMLSerialize<T>(T entity)
        {
            StringBuilder buffer = new StringBuilder();

            XmlSerializer serializer = new XmlSerializer(typeof(T));
            using (TextWriter writer = new StringWriter(buffer))
            {
                serializer.Serialize(writer, entity);
            }

            return buffer.ToString();
        }

        /// <summary>
        /// 将字符串序列化为实体类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xmlString"></param>
        /// <returns></returns>
        public static T DeXMLSerialize<T>(string xmlString)
        {
            T cloneObject = default(T);

            StringBuilder buffer = new StringBuilder();
            buffer.Append(xmlString);

            XmlSerializer serializer = new XmlSerializer(typeof(T));

            using (TextReader reader = new StringReader(buffer.ToString()))
            {
                Object obj = serializer.Deserialize(reader);
                cloneObject = (T)obj;
            }

            return cloneObject;
        }

        public static string ToString(object source, Type type, Encoding encoding)
        {
            // The string to hold the object content
            String content;

            // Create a memoryStream into which the data can be written and readed
            using (var stream = new MemoryStream())
            {
                // Create the xml serializer, the serializer needs to know the type
                // of the object that will be serialized
                var xmlSerializer = new XmlSerializer(type);

                // Create a XmlTextWriter to write the xml object source, we are going
                // to define the encoding in the constructor
                using (var writer = new XmlTextWriter(stream, encoding))
                {
                    // Save the state of the object into the stream
                    xmlSerializer.Serialize(writer, source);

                    // Flush the stream
                    writer.Flush();

                    // Read the stream into a string
                    using (var reader = new StreamReader(stream, encoding))
                    {
                        // Set the stream position to the begin
                        stream.Position = 0;

                        // Read the stream into a string
                        content = reader.ReadToEnd();
                    }
                }
            }

            // Return the xml string with the object content
            return content;
        }
        
        /// <summary>
        /// 去除头部文件的序列化之后的结果
        /// </summary>
        /// <param name="Obj"></param>
        /// <param name="type"></param>
        /// <param name="encoding"></param>
        /// <returns></returns>
        public static string ObjectToXmlSerializer(Object Obj, Type type, Encoding encoding)
        {
            //学习途径
            //https://www.cnblogs.com/kissdodog/archive/2013/12/10/3468385.html
            XmlWriterSettings settings = new XmlWriterSettings();

            //去除xml声明
            settings.OmitXmlDeclaration = true;
            settings.Encoding = encoding;
            using (System.IO.MemoryStream mem = new MemoryStream())
            {
                using (XmlWriter writer = XmlWriter.Create(mem, settings))
                {
                    //去除默认命名空间xmlns:xsd和xmlns:xsi
                    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                    ns.Add("", "");
                    XmlSerializer formatter = new XmlSerializer(type);
                    formatter.Serialize(writer, Obj, ns);
                }
                return encoding.GetString(mem.ToArray());
            }
        }

        #region 不可知的

        public static string DataContractSerializer<T>(T entity)
        {
            StringBuilder buffer = new StringBuilder();
            DataContractSerializer ser = new DataContractSerializer(typeof(T));
            using (XmlWriter writer = XmlWriter.Create(buffer))
            {
                ser.WriteObject(writer, entity);
            }
            return buffer.ToString();
        }

        public static T DeDataContractSerializer<T>(string xmlString)
        {
            T cloneObject = default(T);

            StringBuilder buffer = new StringBuilder();
            buffer.Append(xmlString);

            DataContractSerializer serializer = new DataContractSerializer(typeof(T));

            using (XmlReader reader = XmlReader.Create(buffer.ToString()))
            {
                cloneObject = (T)serializer.ReadObject(reader);
            }

            return cloneObject;
        }
        #endregion


       


    }
}
